package com.kc.config.shiro;

import com.kc.ExceptionHandler.UndowException;
import com.kc.service.*;
import com.kc.util.JWTutil;
import com.kc.util.JwtToken;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class Myrealm extends AuthorizingRealm {

    @Resource
    private IUserAccountService userAccountService;

    @Resource
    private IGroudService groudService;

    @Resource
    private IGroundAccountService groundAccountService;

    @Resource
    private IGroudPermissionService groudPermissionService;

    private static Logger logger = LoggerFactory.getLogger(Myrealm.class);

    //Shiro在进行登录验证时候，会检查Realm是否支持该Token，如果不支持跳过当前Realm，继续下一个Realm。

    public Myrealm() {
        super();
    }

    //支持的Token类的class
    @Override
    public Class getAuthenticationTokenClass() {
        return JWTutil.class;
    }

    //定义角色
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("---------进入动态加载权限------------");

        //写入自动以的role
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //获取token
        Object token = principalCollection.getPrimaryPrincipal();
        String accountId = userAccountService.getAccount((String) token);

        //添加角色和权限
        Set<String> roles = new HashSet<>();
        Set<String> Permission = new HashSet<>();
        List<String> groud = groudService.GetAllRole(groundAccountService.GetGroudId(accountId));
        List<String> GetPermission = groudPermissionService.GetPermission(groundAccountService.GetGroudId(accountId));

        if (groud!=null&&GetPermission!=null){
            //因为这里都是一致的根据角色的id进行查询所以直接这样。
            for (String s: groud){
                roles.add(s);
                Permission.add(s);
            }
        }else {
            throw new UndowException("没有找到角色或权限，登录发生异常");
        }

        info.setRoles(roles);
        info.setStringPermissions(Permission);

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.info("--------------进入shiro认证方法------------------");
        //获取token
        String token = (String) authenticationToken.getCredentials();

        if (JWTutil.Analysis(token)){
            String accountId = userAccountService.getAccount(token);
            if (accountId == null){
                throw new UndowException("这是一个伪造的token");
            }
            return new SimpleAuthenticationInfo(token, token, this.getClass().getSimpleName());
        }else {
            throw new UndowException("token已经失效或者无效token");
        }
    }

    /**
     * 必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }
}
